#include "qopenharmonywindowcontrol.h"
#include <qopenharmonydefines.h>
#include <QHash>
#include "qopenharmonyplayercontrol.h"
#include "qopenharmonywindowadapter.h"

#ifndef QT_NO_WIDGETS
#include <QtGui/QPalette>
#include <QtWidgets/QWidget>
#endif
typedef QHash<QString, QOpenHarmonyWindowControl *> PlayerControls;
Q_GLOBAL_STATIC(PlayerControls, g_controls)

static QOpenHarmonyWindowControl *getControl(OH_NativeXComponent *component)
{
    char id[OH_XCOMPONENT_ID_LEN_MAX + 1] = { };
    uint64_t id_length = OH_XCOMPONENT_ID_LEN_MAX + 1;

    int32_t ret = OH_NativeXComponent_GetXComponentId(component, id, &id_length);
    if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
        return nullptr;
    }
    LOGI("get player xcomponent succeded %{public}s", id);
    QString name = QString::fromUtf8(id);
    return g_controls->value(name);
}

QOpenHarmonyWindowControl::QOpenHarmonyWindowControl(QObject *parent)
    : QVideoWindowControl(parent)
{

}

QOpenHarmonyWindowControl::~QOpenHarmonyWindowControl()
{
    if (m_callback != nullptr)
        delete m_callback;
    g_controls->remove(m_name);
}


WId QOpenHarmonyWindowControl::winId() const
{
    return m_windowId;
}

void QOpenHarmonyWindowControl::setWinId(WId id)
{
    if (m_windowId == id)
        return;
    m_windowId = id;

    static int componentId = 0;
    QString componentIdStr = QString("player_component_id%1").arg(componentId++);
    QString libName = "plugins_mediaservice_qtmedia_openharmony";
    XComponentModel *model = new XComponentModel(componentIdStr.toStdString(), XComponentType::SURFACE, libName.toStdString());
    NodeParams nodeParams("100%", "100%", "0", "0", NodeType::XComponent, model);
    QOpenHarmonyWindowAdapter::AddChildNode(id, &nodeParams);
    g_controls->insert(componentIdStr, this);
    m_name = componentIdStr;
}

QRect QOpenHarmonyWindowControl::displayRect() const
{
    return m_displayRect;
}

void QOpenHarmonyWindowControl::setDisplayRect(const QRect &rect)
{
    m_displayRect = rect;
}

bool QOpenHarmonyWindowControl::isFullScreen() const
{
    return m_fullScreen;
}

void QOpenHarmonyWindowControl::setFullScreen(bool fullScreen)
{
    emit fullScreenChanged(m_fullScreen = fullScreen);
}

void QOpenHarmonyWindowControl::repaint()
{

}

QSize QOpenHarmonyWindowControl::nativeSize() const
{
    return m_playerControl == nullptr ? QSize() : m_playerControl->videoSize();
}

Qt::AspectRatioMode QOpenHarmonyWindowControl::aspectRatioMode() const
{
    return m_aspectRatioMode;
}

void QOpenHarmonyWindowControl::setAspectRatioMode(Qt::AspectRatioMode mode)
{
    m_aspectRatioMode = mode;
}

int QOpenHarmonyWindowControl::brightness() const
{
    return m_brightness;
}

void QOpenHarmonyWindowControl::setBrightness(int brightness)
{
    m_brightness = brightness;

    emit brightnessChanged(brightness);
}

int QOpenHarmonyWindowControl::contrast() const
{
    return m_contrast;
}

void QOpenHarmonyWindowControl::setContrast(int contrast)
{
    m_contrast = contrast;

    emit contrastChanged(contrast);
}

int QOpenHarmonyWindowControl::hue() const
{
    return m_hue;
}

void QOpenHarmonyWindowControl::setHue(int hue)
{
    m_hue = hue;

    emit hueChanged(hue);
}

int QOpenHarmonyWindowControl::saturation() const
{
    return m_saturation;
}

void QOpenHarmonyWindowControl::setSaturation(int saturation)
{
    m_saturation = saturation;

    emit saturationChanged(saturation);
}

void QOpenHarmonyWindowControl::setNativeXComponent(OH_NativeXComponent *nativeXComponent)
{
    m_callback = new OH_NativeXComponent_Callback;
    m_callback->OnSurfaceCreated = &QOpenHarmonyWindowControl::onSurfaceCreated;
    int32_t ret = OH_NativeXComponent_RegisterCallback(nativeXComponent, m_callback);
    if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
        LOGI("set surface touch callback failed");
    }
}

void QOpenHarmonyWindowControl::setNativeWindow(OHNativeWindow *nativeWindow)
{
    m_nativeWindow = nativeWindow;
    QMetaObject::invokeMethod(this, "windowCreated");
}

OHNativeWindow *QOpenHarmonyWindowControl::nativeWindow() const
{
    return m_nativeWindow;
}

void QOpenHarmonyWindowControl::setPlayerControl(QOpenHarmonyPlayerControl *control)
{
    if (control == nullptr)
        return;
    m_playerControl = control;
}

void QOpenHarmonyWindowControl::onSurfaceCreated(OH_NativeXComponent *component, void *window)
{
    if (component != nullptr) {
        QOpenHarmonyWindowControl *control = getControl(component);
        if (control == nullptr)
            return;
        OHNativeWindow *nativeWindow = static_cast<OHNativeWindow *>(window);
        control->setNativeWindow(nativeWindow);
    }
}

void QOpenHarmonyWindowControl::init(napi_env env, napi_value exports)
{
    napi_value exportInstance = nullptr;
    OH_NativeXComponent *nativeXComponent = nullptr;
    int32_t ret;
    char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = { };
    uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;

    if (napi_ok != napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance))
        return;
    if (napi_ok != napi_unwrap(env, exportInstance, reinterpret_cast<void**>(&nativeXComponent)))
        return;
    if (nativeXComponent != nullptr) {
        QOpenHarmonyWindowControl *control = getControl(nativeXComponent);
        if (control == nullptr)
            return;
        control->setNativeXComponent(nativeXComponent);
    }
}
